home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1999 March
/
EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso
/
earcd
/
-archivi
/
-recent2
/
amhelios.lha
/
AmHelios
/
helios.cpp
< prev
next >
Wrap
Text File
|
1997-07-13
|
76KB
|
2,380 lines
////////////////////////////////////////////////////////////
//
// HELIOS.CPP - Radiosity Renderer for MS-Windows Main
// Module
//
// Version: 1.03A
//
// History: 94/08/23 - Version 1.00A release.
// 94/09/07 - Added CheckAbort and user-
// requested abort logic.
// - Added WM_QUERYENDSESSION and
// WM_CLOSE message handlers.
// - Added AbortCalc modeless dialog
// box.
// 94/09/23 - Added elapsed calculation time to
// Convergence Statistics message
// box.
// 94/09/27 - Modified IDM_SETCONVERGE case
// logic to prevent Rendering menu
// option from being enabled when
// display type is H_NONE.
// 94/10/02 - Made Set Camera and Specify
// View dialog boxes modeless.
// - Revised cursor display logic.
// 94/10/14 - Added ContrastError string.
// - Modified SetDisplay dialog box
// function.
// 94/11/19 - Added OutOfMemory error reporting
// for SynCamera::Preview,
// SynCamera::Shoot, WinBitmap::Open
// and WinBitmap::Display function
// call failures.
// 94/11/25 - Added CenterDialog and
// FileOpenHook functions.
// - Modified SetEntityDir, SetCamera,
// SetView, SetConverge, AbortCalc,
// SetDisplay, and About to center
// dialog boxes.
// 94/12/01 - Added palette flag and
// color resolution initialization
// to InitInstance.
// - Added color resolution logic to
// SetDisplay dialog box.
// 94/12/04 - Added bitmap color quantization
// capability to IDM_RENDER,
// IDM_REDISPLAY and IDD_UPD_DISPLAY
// case logic.
// - Added modeless RenderMsg dialog
// box.
// 94/12/06 - Added WM_QUERYPALETTE and
// WM_PALETTECHANGED message
// handlers.
// - Deleted <windows.h>, <stdio.h>
// and <math.h> include directives.
// - Added "general.h" include
// directive.
// - Made SetDisplay dialog box
// modeless.
// - Added check for invalid display
// type to InitInstance.
// - Added AppTitle string.
// 94/12/08 - Added IDM_HELP_CONTENTS and
// IDM_HELP_HELP case logic.
// - Added Windows Help cancel to
// WM_DESTROY case logic.
// - Added HelpFileName string.
// - Added "win_help.h" include
// directive.
// 94/12/11 - Revised FrontDistErr string.
// 94/12/16 - Version 1.01A release.
// 94/12/19 - Changed OutputFilterSpec string
// to support TARGA files.
// - Changed IDM_SAVEAS case logic to
// support TARGA files.
// - Added static WinTarga object.
// - Added "win_tga.h" include
// directive.
// 94/12/24 - Modified SetCamera to handle
// window scale and projection type.
// - Added WindowScaleError string.
// 95/02/05 - Version 1.02A release.
// 95/03/09 - Modified IDM_FILEOPEN case logic
// to prevent GetSaveFileName from
// overwriting hook function pointer.
// 95/03/26 - Revised IDM_RENDER case logic to
// support antialiasing.
// - Added hourglass cursor to
// IDM_FILEOPEN case logic.
// - Deleted RenderInProgress and
// QuantInProgress strings.
// - Added IDM_SETCOLOR case.
// - Added SetColor function.
// - Made pScroll and DispType global.
// - Added DisplayBitmap function.
// 95/06/26 - Modified SetCamera, SetView,
// SetDisplay and SetColor to
// update display when OK button
// selected.
// 95/07/16 - Revised menu item graying logic.
// - Added DisableMenu and EnableMenu
// functions.
// - Revised IDM_REDISPLAY case logic
// to properly handle redisplay when
// no bitmap is currently displayed.
// - Added RadCalcDone flag.
// 95/07/21 - Version 1.02B release.
// 95/09/30 - Revised About function to
// properly respond to WM_COMMAND
// messages under Windows NT.
// 95/10/10 - Revised WM_HSCROLL and WM_VSCROLL
// case statements to process scroll
// bar messages under Windows NT.
// 96/02/14 - Version 1.02C release.
// 96/02/21 - Modified DisplayBitmap to call
// SynCamera::Abort.
// 96/02/29 - Modified IDM_FILEOPEN case logic
// to initialize camera view system.
// 96/03/30 - Added camera focus position to
// SetView dialog box handler.
// - Added IDM_STATISTICS case.
// - Added DisplayStats function.
// - Modified DisableMenu and
// EnableMenu functions.
// - Deleted Environment Statistics
// message box function call from
// IDM_FILEOPEN case statement.
// - Modified IDM_FILEOPEN case logic
// to display default wireframe view
// of environment.
// - Added IDM_SETDOLLY, IDM_SETORBIT,
// IDM_SETPAN, IDM_SETROTATE,
// IDM_SETTILT, IDM_SETZOOM,
// IDM_DEFVIEW, WM_LBUTTONDOWN,
// WM_LBUTTONUP and WM_RBUTTONDOWN
// case statements.
// - Made menu handle in MainWndProc
// static and initialized from
// from WM_CREATE case statement.
// - Added MoveType global variable.
// - Added SetMovementType,
// UpdateDolly, UpdateOrbit,
// UpdatePan, UpdateRotate,
// UpdateTilt, UpdateZoom,
// UpdateCameraDialog and
// UpdateViewDialog functions.
// - Modified DisableMenu and
// EnableMenu functions.
// - Added camera tilt field to
// SetCamera.
// - Removed View Direction and
// View-Up Vector fields from
// SetView.
// - Deleted HorzError, VertError,
// ViewDirName, ViewUpName and
// ViewUpError static strings.
// - Added FocusError and TiltError
// static strings.
// - Deleted "spheric3.h" include
// directive.
// 96/04/01 - Version 1.03A release.
//
// Compilers: Microsoft Visual C/C++ Professional V1.5
// Borland C++ Version 4.5
//
// Author: Ian Ashdown, P.Eng.
// byHeart Software Limited
// 620 Ballantree Road
// West Vancouver, B.C.
// Canada V7S 1W3
// Tel. (604) 922-6148
// Fax. (604) 987-7621
//
// Copyright 1994-1996 byHeart Software Limited
//
// The following source code has been derived from:
//
// Ashdown, I. 1994. Radiosity: A Programmer's
// Perspective. New York, NY: John Wiley & Sons.
//
// It may be freely copied, redistributed, and/or modified
// for personal use ONLY, as long as the copyright notice
// is included with all source code files.
//
////////////////////////////////////////////////////////////
#include "general.h"
#include <windowsx.h>
#include <commdlg.h>
#include "error.h"
#include "parse.h"
#include "syn_cam.h"
#include "win_bmap.h"
#include "win_tga.h"
#include "win_meta.h"
#include "win_sbar.h"
#include "win_help.h"
#if (defined(_HEMI_CUBE) || defined(_CUBIC_TETRA))
#include "prog_rad.h"
#elif defined(_RAY_CAST)
#include "ray_rad.h"
#else
#include "rad_eqn.h"
#endif
#include "resource.h"
#include "helios.h"
static BOOL AbortFlag = FALSE; // User-requested abort
static BOOL InCalc = FALSE; // Calculations in progress
// Radiosity calculations completed
static BOOL RadCalcDone = FALSE;
static char EntityDir[MaxLen]; // Entity directory
static char WorldName[MaxLen]; // World file name buffer
static char BitmapName[MaxLen]; // Bitmap file name buffer
static char FileTitle[MaxLen]; // File title buffer
static char StrBuffer[MaxLen]; // Temporary string buffer
static int DispType = H_NONE; // Display type
static int MoveType = H_LOCK; // Camera movement type
static HINSTANCE hInst; // Current instance handle
// Dialog box handles
static HWND hAbortDlg; // Abort calculations
static HWND hQuantDlg; // Quantization message
static HWND hRenderDlg; // Rendering message
static HWND hSetCameraDlg; // Camera parameters
static HWND hSetColorDlg; // Color parameters
static HWND hSetDisplayDlg; // Display parameters
static HWND hSetViewDlg; // View parameters
// Dialog box exported function prolog pointers
static DLGPROC pcfunc; // Camera parameters
static DLGPROC pdfunc; // Display parameters
static DLGPROC pofunc; // Coloor parameters
static DLGPROC pvfunc; // View parameters
static OPENFILENAME Ofn; // Open filename structure
// Synthetic camera
static SynCamera Camera(640, 480, -180.0, 90.0, 0.0, 0.0);
static Environ Environment; // Environment
static Parse Parser; // World file parser
static WinBitmap Bitmap; // Bitmap manager
static WinMetaFile Wire; // Metafile manager
static WinScroll *pScroll; // Scroll bar manager ptr
static WinTarga Targa; // Targa file manager
// Radiosity equation solver
#if (defined(_HEMI_CUBE) || defined(_CUBIC_TETRA))
static ProgRad Radiosity; // Progressive radiosity
#elif defined(_RAY_CAST)
static RayRad Radiosity; // Ray cast radiosity
#else
static RadEqnSolve Radiosity; // Dummy equation solver
#endif
static const char AppName[] = "HELIOS";
static const char AppTitle[] = "HELIOS Radiosity Renderer";
static const char BitmapSection[] = "Bitmap";
static const char CalcInProgress[] = "Radiosity "
"calculations in progress ...";
static const char ContrastError[] = "Contrast factor must "
"be greater than zero";
static const char EyeDistError[] = "Front distance is "
"behind eye position";
static const char FocusError[] = "Focus position cannot be"
"equal to eye position";
static const char FrontDistError[] = "Front distance must "
"be greater than back distance";
static const char GammaError[] = "Gamma value must be "
"greater than zero";
static const char HeightEntry[] = "Height";
static const char HelpFileName[] = "HELIOS.HLP";
static const char InitFileName[] = "HELIOS.INI";
static const char InvalidDisplay[] = "HELIOS requires a "
"display with at least 256 colors";
static const char MaxStepError[] = "Maximum number of "
"steps must be between 1 and 2000";
static const char NoiseError[] = "Noise level must be "
"between 0 and 8";
static const char PixelError[] = "Pixel values must be "
"between 32 and 1024";
static const char StopError[] = "Stopping criterion must be"
"between 0.0 and 1.0";
static const char TiltError[] = "Tilt angle must be between"
" 0.0 and 360.0 degrees";
static const char WidthEntry[] = "Width";
static const char ViewDistError[] = "View distance must be "
"greater than zero";
static const char WindowScaleError[] = "Window scaling "
"factor must be greater than zero";
static const char WireClass[] = "WIRE";
// File type filters
static const char InputFilterSpec[128] =
"World Files (*.WLD)\0*.WLD\0All Files (*.*)\0*.*\0";
static const char OutputFilterSpec[128] =
"BMP Files (*.BMP)\0*.BMP\0TARGA Files (*.TGA)\0*.TGA\0";
static const int MaxStep = 2000;
static const int MinPixel = 32;
static const int MaxPixel = 1024;
int WINAPI WinMain( HINSTANCE hinstance, HINSTANCE hpinst,
LPSTR pcmdline, int cmdshow )
{
MSG msg; // Window message
// Initialize user-request abort flag
AbortFlag = FALSE;
// Other instances of application running ?
if (!hpinst)
if (!InitApplication(hinstance))
return FALSE;
// Initialize current instance
if (!InitInstance(hinstance, cmdshow))
return FALSE;
// Process window messages
while (GetMessage(&msg, NULL, NULL, NULL))
{
// Check for "Set Camera" dialog message
if (hSetCameraDlg != NULL)
if (IsDialogMessage(hSetCameraDlg, &msg) == TRUE)
continue;
// Check for "Set Color Parameters" dialog message
if (hSetColorDlg != NULL)
if (IsDialogMessage(hSetColorDlg, &msg) == TRUE)
continue;
// Check for "Set Display Parameters" dialog message
if (hSetDisplayDlg != NULL)
if (IsDialogMessage(hSetDisplayDlg, &msg) == TRUE)
continue;
// Check for "Specify View" dialog message
if (hSetViewDlg != NULL)
if (IsDialogMessage(hSetViewDlg, &msg) == TRUE)
continue;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
// Initialize window data and register window classes
static BOOL InitApplication( HINSTANCE hinstance )
{
WNDCLASS wc; // Window class
// Register main window class
wc.style = CS_VREDRAW | CS_HREDRAW;
wc.lpfnWndProc = (WNDPROC) MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hinstance;
#if defined(_CUBIC_TETRA)
wc.hIcon = LoadIcon(hinstance, "HELIOS_C");
#elif defined(_HEMI_CUBE)
wc.hIcon = LoadIcon(hinstance, "HELIOS_H");
#elif defined(_RAY_CAST)
wc.hIcon = LoadIcon(hinstance, "HELIOS_R");
#else
wc.hIcon = LoadIcon(hinstance, "HELIOS_S");
#endif
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) GetStockObject(LTGRAY_BRUSH);
wc.lpszMenuName = "HeliosMenu";
wc.lpszClassName = AppName;
if (!RegisterClass(&wc))
return FALSE;
// Register wireframe window class
wc.lpfnWndProc = (WNDPROC) WireWndProc;
wc.hIcon = NULL;
wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wc.lpszClassName = WireClass;
return (RegisterClass(&wc) ? TRUE : FALSE);
}
// Save instance handle and create main window
static BOOL InitInstance( HINSTANCE hinstance, int
cmdshow )
{
HDC hdc; // Device context
HWND hwnd; // Main window handle
hInst = hinstance; // Save current instance handle
// Create main window for current instance
hwnd = CreateWindow(AppName, AppTitle,
WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, NULL, NULL, hinstance, NULL);
if (hwnd == 0)
return FALSE;
// Initialize open filename structure
Ofn.lStructSize = sizeof(OPENFILENAME);
Ofn.hwndOwner = hwnd;
Ofn.lpstrFilter = NULL;
Ofn.lpstrCustomFilter = NULL;
Ofn.nMaxCustFilter = 0;
Ofn.nFilterIndex = 1;
Ofn.lpstrFile = NULL;
Ofn.nMaxFile = MaxLen;
Ofn.lpstrInitialDir = NULL;
Ofn.lpstrFileTitle = FileTitle;
Ofn.nMaxFileTitle = MaxLen;
Ofn.lpstrTitle = NULL;
Ofn.lpstrDefExt = NULL;
// Initialize modeless dialog box handles
hSetCameraDlg = NULL;
hSetColorDlg = NULL;
hSetDisplayDlg = NULL;
hSetViewDlg = NULL;
hdc = GetDC(NULL); // Get screen device context
// Determine display device capabilities
if ((GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE) == 0)
{
// Check for 15-bit or better display
if (GetDeviceCaps(hdc, BITSPIXEL) < 15)
{
MessageBox(NULL, InvalidDisplay, AppTitle, MB_OK);
ReleaseDC(NULL, hdc);
return FALSE;
}
// No palette
Bitmap.SetPaletteFlag(FALSE);
Bitmap.SetRGBFlag(TRUE);
}
else
{
// Check for 256-color display
if (GetDeviceCaps(hdc, COLORRES) < 8)
{
MessageBox(NULL, InvalidDisplay, AppTitle, MB_OK);
ReleaseDC(NULL, hdc);
return FALSE;
}
// Palette-mapped display
Bitmap.SetPaletteFlag(TRUE);
Bitmap.SetRGBFlag(FALSE);
}
ReleaseDC(NULL, hdc); // Release device context
ShowWindow(hwnd, cmdshow); // Show the window
UpdateWindow(hwnd); // Paint the client area
return TRUE;
}
// Main window message handler
LRESULT WINAPI MainWndProc( HWND hwnd, UINT msg, WPARAM
wparam, LPARAM lparam )
{
static short client_x; // Client area width
static short client_y; // Client area height
static short mouse_x; // Mouse x-axis position
static short mouse_y; // Mouse y-axis position
static short wire_x; // Wireframe window width
static short wire_y; // Wireframe window height
static HWND hwnd_wire; // Wireframe window handle
static HMENU hmenu; // Menu handle
int mouse_dx; // Mouse x-axis delta
int mouse_dy; // Mouse y-axis delta
BOOL redraw; // Redraw flag
BOOL status; // Status flag
DLGPROC pfunc; // Exported fcn prolog ptr
HCURSOR hcursor; // Cursor handle
HDC hdc; // Device context handle
PAINTSTRUCT ps; // Window paint structure
POINT pos; // Point co-ordinates
RECT rc; // Rectangle co-ordinates
switch (msg)
{
case WM_CREATE: // Create window
// Instantiate scroll bar manager
pScroll = new WinScroll(hwnd);
hmenu = GetMenu(hwnd); // Get menu handle
// Create dialog box procedure instance thunks
pcfunc = (DLGPROC) MakeProcInstance((FARPROC)
SetCamera, hInst);
pdfunc = (DLGPROC) MakeProcInstance((FARPROC)
SetDisplay, hInst);
pofunc = (DLGPROC) MakeProcInstance((FARPROC)
SetColor, hInst);
pvfunc = (DLGPROC) MakeProcInstance((FARPROC)
SetView, hInst);
break;
case WM_SIZE: // Get client area dimensions
client_x = LOWORD(lparam);
client_y = HIWORD(lparam);
switch (DispType)
{
case H_WIRE:
// Update wireframe display
CalcWireDim(client_x, client_y, &wire_x, &wire_y);
MoveWindow(hwnd_wire, Offset, Offset, wire_x,
wire_y, TRUE);
break;
case H_BMAP:
// Set scroll bar manager
pScroll->Set(Camera.GetWidth(),
Camera.GetHeight());
break;
default:
break;
}
break;
case WM_PAINT: // Paint client area
hdc = BeginPaint(hwnd, &ps);
if (DispType == H_BMAP) // Display bitmap ?
{
GetClientRect(hwnd, &rc);
pos = pScroll->Pos();
if (Bitmap.Display(hdc, pos, rc) == FALSE)
{
DispType = H_NONE;
pScroll->Hide();
OutOfMemory();
}
}
EndPaint(hwnd, &ps);
break;
case WM_HSCROLL: // Process horz scroll bar message
pScroll->Horz(GET_WM_HSCROLL_CODE(wparam, lparam),
GET_WM_HSCROLL_POS(wparam, lparam));
break;
case WM_VSCROLL: // Process vertical scroll bar msg
pScroll->Vert(GET_WM_VSCROLL_CODE(wparam, lparam),
GET_WM_VSCROLL_POS(wparam, lparam));
break;
case WM_KEYDOWN: // Process key down message
DoKeyDown(hwnd, wparam);
break;
case WM_LBUTTONDOWN: // Process left button down
if (MoveType != H_LOCK && InCalc == FALSE)
{
// Save current mouse coordinates
mouse_x = LOWORD(lparam);
mouse_y = HIWORD(lparam);
SetCapture(hwnd); // Capture mouse input
}
break;
case WM_LBUTTONUP: // Process left button up
if (MoveType != H_LOCK && InCalc == FALSE)
{
ReleaseCapture(); // Release mouse
// Calculate mouse movement
mouse_dx = (int) LOWORD(lparam) - (int) mouse_x;
mouse_dy = (int) mouse_y - (int) HIWORD(lparam);
switch (MoveType) // Process camera movement
{
case H_DOLLY:
UpdateDolly(mouse_dy);
break;
case H_ORBIT:
UpdateOrbit(mouse_dx, mouse_dy);
break;
case H_PAN:
UpdatePan(mouse_dx, mouse_dy);
break;
case H_ROTATE:
UpdateRotate(mouse_dx, mouse_dy);
break;
case H_TILT:
UpdateTilt(mouse_dx);
break;
case H_ZOOM:
UpdateZoom(mouse_dy);
break;
}
// Display wireframe
SendMessage(hwnd, WM_COMMAND, IDD_UPD_DISPLAY, 0L);
}
break;
case WM_RBUTTONDOWN: // Process right button down
if (InCalc == FALSE)
{
// Get current mouse cursor coordinates
pos = MAKEPOINT(lparam);
// Check whether mouse cursor is in client area
GetClientRect(hwnd, &rc);
if (PtInRect(&rc, pos) == TRUE)
{
// Convert mouse position to screen coordinates
ClientToScreen(hwnd, &pos);
// Display Interactive popup menu
TrackPopupMenu(GetSubMenu(GetSubMenu(hmenu,
MENU_CAMERA_POS), MENU_INTERACTIVE_POS),
TPM_LEFTALIGN | TPM_LEFTBUTTON, pos.x, pos.y,
0, hwnd, NULL);
}
}
break;
case WM_QUERYENDSESSION: // Terminate Windows session
if (InCalc == TRUE)
{
MessageBox(hwnd, CalcInProgress, AppName,
MB_ICONINFORMATION | MB_OK);
return NULL;
}
else
return 1L;
case WM_CLOSE: // Terminate application
if (InCalc == TRUE)
MessageBox(hwnd, CalcInProgress, AppName,
MB_ICONINFORMATION | MB_OK);
else
DestroyWindow(hwnd); // Close main window
break;
case WM_QUERYNEWPALETTE: // New palette required ?
case WM_PALETTECHANGED: // System palette changed
if (DispType == H_BMAP)
Bitmap.Redisplay(hwnd); // Redisplay bitmap
break;
case WM_COMMAND: // Process window message
switch (GET_WM_COMMAND_ID(wparam, lparam))
{
case IDM_FILEOPEN: // Open file
Ofn.lpstrDefExt = "WLD";
Ofn.lpstrFilter = InputFilterSpec;
Ofn.lpstrFile = WorldName;
Ofn.Flags = OFN_HIDEREADONLY | OFN_READONLY |
OFN_ENABLEHOOK;
Ofn.lpfnHook = (UINT (CALLBACK *)(HWND, UINT,
WPARAM, LPARAM)) MakeProcInstance((FARPROC)
FileOpenHook, hInst);
if (GetOpenFileName((LPOPENFILENAME) &Ofn))
{
switch (DispType)
{
case H_WIRE:
// Erase wireframe metafile
Wire.Erase();
DispType = H_NONE;
// Close wireframe window
DestroyWindow(hwnd_wire);
break;
case H_BMAP:
Bitmap.Close(); // Close bitmap
DispType = H_NONE;
pScroll->Hide(); // Hide scroll bars
// Disable Save As menu item
EnableMenuItem(hmenu, IDM_SAVEAS,
MF_GRAYED);
InvalidateRect(hwnd, NULL, TRUE);
break;
default:
break;
}
// Display hourglass cursor
hcursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
// Parse environment file
if ((Parser.ParseFile(Ofn.lpstrFile, EntityDir,
&Environment)) == TRUE)
{
// Update window title
wsprintf(StrBuffer, "HELIOS - %s",
Ofn.lpstrFile);
SetWindowText(hwnd, StrBuffer);
// Initialize camera view system
Camera.InitViewSystem(&Environment);
// Display wireframe
SendMessage(hwnd, WM_COMMAND, IDM_WIREFRAME,
0L);
// Enable display statistics menu item
EnableMenuItem(hmenu, IDM_STATISTICS,
MF_ENABLED);
// Enable rendering menu items
EnableMenuItem(hmenu, IDM_WIREFRAME,
MF_ENABLED);
EnableMenuItem(hmenu, IDM_SHADED,
MF_ENABLED);
EnableMenuItem(hmenu, IDM_RENDER,
MF_ENABLED);
// Disable Redisplay menu item
EnableMenuItem(hmenu, IDM_REDISPLAY,
MF_GRAYED);
// Reset radiosity calculations done flag
RadCalcDone = FALSE;
// Initialize camera view system
Camera.InitViewSystem(&Environment);
}
SetCursor(hcursor); // Redisplay old cursor
}
FreeProcInstance((FARPROC) Ofn.lpfnHook);
break;
case IDM_SAVEAS: // Save BMP file
Ofn.lpstrDefExt = "BMP";
Ofn.lpstrFilter = OutputFilterSpec;
Ofn.lpstrFile = BitmapName;
Ofn.Flags = OFN_OVERWRITEPROMPT |
OFN_HIDEREADONLY;
if (GetSaveFileName((LPOPENFILENAME) &Ofn))
{
// Write bitmap file
switch (Ofn.nFilterIndex)
{
case 1: // BMP format
status = Bitmap.Write(Ofn.lpstrFile);
break;
case 2: // TARGA format
status = Targa.Write(Bitmap.GetBitmapPtr(),
Bitmap.GetPalettePtr(),
Bitmap.GetWidth(), Bitmap.GetHeight(),
Bitmap.GetScanWidth(),
Bitmap.GetNumColors(),
Ofn.lpstrFile);
break;
default: // Unrecognized format
status = FALSE;
break;
}
if (status == FALSE) // Check for error
{
sprintf(StrBuffer, "Could not save file %s",
Ofn.lpstrFile);
ReportError(StrBuffer);
}
}
break;
case IDM_EXIT: // Exit application
DestroyWindow(hwnd);
break;
case IDM_SETCAMERA: // Set camera parameters
if (hSetCameraDlg == NULL)
hSetCameraDlg = CreateDialog(hInst, "SetCamera",
hwnd, (DLGPROC) pcfunc);
break;
case IDM_SETVIEW: // Specify view direction
if (hSetViewDlg == NULL)
hSetViewDlg = CreateDialog(hInst, "SetView",
hwnd, (DLGPROC) pvfunc);
break;
case IDM_SETDOLLY: // Toggle camera dolly
case IDM_SETORBIT: // Toggle camera orbit
case IDM_SETPAN: // Toggle camera pan
case IDM_SETROTATE: // Toggle camera rotate
case IDM_SETTILT: // Toggle camera tilt
case IDM_SETZOOM: // Toggle camera zoom
SetMovementType(hmenu, GET_WM_COMMAND_ID(wparam,
lparam));
break;
case IDM_DEFVIEW: // Display default view
// Initialize camera view system
Camera.InitViewSystem(&Environment);
// Update modeless Camera Parameters dialog box
UpdateCameraDialog();
// Update modeless View Parameters dialog box
UpdateViewDialog();
// Display wireframe
SendMessage(hwnd, WM_COMMAND, IDD_UPD_DISPLAY,
0L);
break;
case IDM_WIREFRAME: // Wireframe display
if (DispType != H_WIRE)
{
if (DispType == H_BMAP)
{
Bitmap.Close(); // Close bitmap
DispType = H_NONE;
pScroll->Hide(); // Hide scroll bars
// Disable Save As menu item
EnableMenuItem(hmenu, IDM_SAVEAS, MF_GRAYED);
InvalidateRect(hwnd, NULL, TRUE);
}
// Create wireframe window
CalcWireDim(client_x, client_y, &wire_x,
&wire_y);
hwnd_wire = CreateWindow(WireClass, NULL,
WS_CHILD | WS_VISIBLE | WS_BORDER |
WS_DISABLED, Offset, Offset, wire_x, wire_y,
hwnd, NULL, hInst, NULL);
DispType = H_WIRE;
// Record wireframe display
if (Camera.Preview(&Environment, &Wire) ==
FALSE)
OutOfMemory();
}
break;
case IDM_SHADED: // Shaded display
case IDM_RENDER: // Radiosity rendering
if (wparam == IDM_RENDER)
{
DisableMenu(hmenu); // Disable menu items
// Reset radiosity calculations done flag
RadCalcDone = FALSE;
// Confirm radiosity equation solver status
if (Radiosity.GetStatus() == FALSE)
{
OutOfMemory();
EnableMenu(hmenu); // Enable menu items
break;
}
// Initialize equation solver
if (Radiosity.Open(&Environment) == FALSE)
{
OutOfMemory();
EnableMenu(hmenu); // Enable menu items
break;
}
// Create modeless radiosity calculations
// dialog box
InCalc = TRUE;
pfunc = (DLGPROC) MakeProcInstance((FARPROC)
AbortCalc, hInst);
hAbortDlg = CreateDialog(hInst, "AbortRad",
hwnd, (DLGPROC) pfunc);
SetDlgItemInt(hAbortDlg, IDC_MAXSTEP,
Radiosity.GetMaxStep(), FALSE);
SetDlgItemFloat(hAbortDlg, IDC_MINSTOP,
Radiosity.GetStopCriterion());
// Perform radiosity calculations
while (Radiosity.Calculate() == FALSE)
{
// Check for user-requested abort
if (CheckAbort() == TRUE)
{
AbortFlag = FALSE;
break;
}
// Display radiosity calculations progress
SetDlgItemInt(hAbortDlg, IDC_NUMSTEP,
Radiosity.GetStepCount(), FALSE);
SetDlgItemFloat(hAbortDlg, IDC_CONVERGE,
Radiosity.GetConvergence());
SetDlgItemText(hAbortDlg, IDC_ELAPSED,
Radiosity.GetElapsedTime());
}
// Close radiosity calculations dialog box
DestroyWindow(hAbortDlg);
FreeProcInstance((FARPROC) pfunc);
UpdateWindow(hwnd);
// Close radiosity equation solver
Radiosity.Close();
InCalc = FALSE;
if (AbortFlag == FALSE)
{
// Set radiosity calculations done flag
RadCalcDone = TRUE;
}
EnableMenu(hmenu); // Enable menu items
}
else
{
// Set vertice exitances to parent surface
// reflectances
Radiosity.Shade(&Environment);
// Reset radiosity calculations done flag
RadCalcDone = FALSE;
}
// Open new bitmap
if (Bitmap.Open(Camera.GetWidth(),
Camera.GetHeight()) == TRUE)
{
// Display bitmap
if (DisplayBitmap(hwnd, hwnd_wire, hmenu) ==
TRUE)
{
if (wparam == IDM_RENDER)
{
MessageBeep(MB_OK); // Signal completion
// Display convergence statistics
sprintf(StrBuffer, "Number of Steps = %d\n"
"Convergence = %f\nElapsed Time = %s",
Radiosity.GetStepCount(),
Radiosity.GetConvergence(),
Radiosity.GetElapsedTime());
MessageBox(hwnd, StrBuffer, "Convergence "
"Statistics", MB_OK |
MB_ICONINFORMATION);
// Disable Rendering menu item
EnableMenuItem(hmenu, IDM_RENDER,
MF_GRAYED);
}
}
else
Bitmap.Close(); // Close bitmap
}
else
OutOfMemory(); // Report error
break;
case IDM_REDISPLAY: // Redisplay bitmap
if (DispType == H_BMAP)
Bitmap.Close(); // Close bitmap
// Open new bitmap
if (Bitmap.Open(Camera.GetWidth(),
Camera.GetHeight()) == TRUE)
{
// Display bitmap
if (DisplayBitmap(hwnd, hwnd_wire, hmenu) ==
FALSE)
Bitmap.Close(); // Close bitmap
}
else
OutOfMemory();
break;
case IDD_UPD_DISPLAY: // Update display
if (DispType == H_BMAP)
{
Bitmap.Close(); // Close bitmap
// Open new bitmap
if (Bitmap.Open(Camera.GetWidth(),
Camera.GetHeight()) == TRUE)
{
// Display bitmap
if (DisplayBitmap(hwnd, hwnd_wire, hmenu) ==
FALSE)
Bitmap.Close(); // Close bitmap
}
else
OutOfMemory(); // Report error
}
else if (DispType == H_WIRE)
{
// Record wireframe display
if (Camera.Preview(&Environment, &Wire) ==
TRUE)
{
// Resize and redraw wireframe window
InvalidateRect(hwnd_wire, NULL, TRUE);
CalcWireDim(client_x, client_y, &wire_x,
&wire_y);
MoveWindow(hwnd_wire, Offset, Offset, wire_x,
wire_y, TRUE);
}
else
OutOfMemory();
}
break;
case IDM_DIRECTORY: // Set entity directory
pfunc = (DLGPROC) MakeProcInstance((FARPROC)
SetEntityDir, hInst);
DialogBox(hInst, "SetEntityDir", hwnd, pfunc);
FreeProcInstance((FARPROC) pfunc);
break;
case IDM_STATISTICS: // Display statistics
pfunc = (DLGPROC) MakeProcInstance((FARPROC)
DisplayStats, hInst);
DialogBox(hInst, "DisplayStats", hwnd, pfunc);
FreeProcInstance((FARPROC) pfunc);
break;
case IDM_SETCONVERGE: // Set convergence
pfunc = (DLGPROC) MakeProcInstance((FARPROC)
SetConverge, hInst);
redraw = DialogBox(hInst, "SetConverge", hwnd,
pfunc);
FreeProcInstance((FARPROC) pfunc);
if (redraw == TRUE)
{
// Reset radiosity calculations done flag
RadCalcDone = FALSE;
// Enable Rendering menu item
EnableMenuItem(hmenu, IDM_RENDER, MF_ENABLED);
}
break;
case IDM_SETDISPLAY: // Set display parameters
if (hSetDisplayDlg == NULL)
hSetDisplayDlg = CreateDialog(hInst,
"SetDisplay", hwnd, (DLGPROC) pdfunc);
break;
case IDM_SETCOLOR: // Set color parameters
if (hSetColorDlg == NULL)
hSetColorDlg = CreateDialog(hInst, "SetColor",
hwnd, (DLGPROC) pofunc);
break;
case IDM_HELP_CONTENTS: // Display Help contents
WinHelp(hwnd, HelpFileName, HELP_CONTENTS, 0L);
break;
case IDM_HELP_HELP: // Display Using Help
WinHelp(hwnd, "WINHELP.HLP", HELP_CONTENTS, 0L);
break;
case IDM_HELP_BOOK: // Display book info
WinHelp(hwnd, HelpFileName, HELP_CONTEXT,
(DWORD) HELP_BOOK);
break;
case IDM_ABOUT: // Display About box
pfunc = (DLGPROC) MakeProcInstance((FARPROC)
About, hInst);
DialogBox(hInst, "AboutBox", hwnd, pfunc);
FreeProcInstance((FARPROC) pfunc);
break;
default:
break;
}
break;
case WM_DESTROY: // Destroy window
delete pScroll; // Delete scroll bar manager
Wire.Erase(); // Erase wireframe metafile
Bitmap.Close(); // Release bitmap memory
// Cancel Windows Help
WinHelp(hwnd, HelpFileName, HELP_QUIT, 0L);
// Release dialog box procedure instance thunks
FreeProcInstance((FARPROC) pcfunc);
FreeProcInstance((FARPROC) pdfunc);
FreeProcInstance((FARPROC) pvfunc);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wparam, lparam);
}
return NULL;
}
// File Open dialog box hook function
UINT CALLBACK FileOpenHook( HWND hdlg, UINT msg, WPARAM
wparam, LPARAM lParam)
{
if (msg == WM_INITDIALOG)
{
CenterDialog(hdlg);
return TRUE;
}
else
return FALSE;
}
// Wireframe window message handler
LRESULT WINAPI WireWndProc( HWND hwnd, UINT msg, WPARAM
wparam, LPARAM lparam )
{
static short client_x; // Client area width
static short client_y; // Client area height
switch (msg)
{
case WM_SIZE:
client_x = LOWORD(lparam);
client_y = HIWORD(lparam);
break;
case WM_PAINT: // Paint client area
Wire.Play(hwnd, Camera.GetWidth(), Camera.GetHeight(),
client_x, client_y);
break;
default:
return DefWindowProc(hwnd, msg, wparam, lparam);
}
return NULL;
}
// Set entities directory
BOOL CALLBACK SetEntityDir( HWND hdlg, UINT msg, WPARAM
wparam, LPARAM lparam )
{
switch (msg)
{
case WM_INITDIALOG:
SetDlgItemText(hdlg, IDC_ENTITY, EntityDir);
CenterDialog(hdlg);
return TRUE;
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wparam, lparam))
{
case IDC_HELP_SETDIR: // Display Help
WinHelp(hdlg, HelpFileName, HELP_CONTEXT,
(DWORD) HELP_SETDIR);
break;
case IDOK:
GetDlgItemText(hdlg, IDC_ENTITY, EntityDir,
sizeof(EntityDir));
EndDialog(hdlg, TRUE);
return TRUE;
case IDCANCEL:
EndDialog(hdlg, FALSE);
return TRUE;
default:
break;
}
break;
default:
break;
}
return FALSE;
}
// Display environment statistics
BOOL CALLBACK DisplayStats( HWND hdlg, UINT msg, WPARAM
wparam, LPARAM lparam )
{
switch (msg)
{
case WM_INITDIALOG:
// Initialize environment statistics
SetDlgItemInt(hdlg, IDC_NUM_INSTANCES,
Environment.GetNumInst(), FALSE);
SetDlgItemInt(hdlg, IDC_NUM_SURFACES,
Environment.GetNumSurf(), FALSE);
SetDlgItemInt(hdlg, IDC_NUM_PATCHES,
Environment.GetNumPatch(), FALSE);
SetDlgItemInt(hdlg, IDC_NUM_ELEMENTS,
Environment.GetNumElem(), FALSE);
SetDlgItemInt(hdlg, IDC_NUM_VERTICES,
Environment.GetNumVert(), FALSE);
CenterDialog(hdlg);
return TRUE;
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wparam, lparam))
{
case IDOK:
EndDialog(hdlg, TRUE);
return TRUE;
default:
break;
}
break;
default:
break;
}
return FALSE;
}
// Set camera parameters
BOOL CALLBACK SetCamera( HWND hdlg, UINT msg, WPARAM
wparam, LPARAM lparam )
{
double vpd, fpd, bpd; // Camera distances
double scale; // Window scaling factor
double tilt; // Camera tilt angle
int w, h; // Bitmap window dimensions
BOOL dummy; // Dummy parameter
static BOOL par_flag; // Parallel projection flag
switch (msg)
{
case WM_INITDIALOG:
// Get camera distances
SetDlgItemFloat(hdlg, IDC_VDIST,
Camera.GetViewDist());
SetDlgItemFloat(hdlg, IDC_FDIST,
Camera.GetFrontDist());
SetDlgItemFloat(hdlg, IDC_BDIST,
Camera.GetBackDist());
// Get window scaling factor
SetDlgItemFloat(hdlg, IDC_SCALE,
Camera.GetWindowScale());
// Get bitmap window dimensions
SetDlgItemInt(hdlg, IDC_HPIXSZ, Camera.GetWidth(),
FALSE);
SetDlgItemInt(hdlg, IDC_VPIXSZ, Camera.GetHeight(),
FALSE);
// Get camera tilt angle
SetDlgItemFloat(hdlg, IDC_CAMTILT,
RadToDeg(Camera.GetTiltAngle()));
// Get projection type
par_flag = Camera.GetParProjFlag();
if (par_flag == TRUE)
CheckRadioButton(hdlg, IDC_PERSPECT, IDC_PARALLEL,
IDC_PARALLEL);
else
CheckRadioButton(hdlg, IDC_PERSPECT, IDC_PARALLEL,
IDC_PERSPECT);
CenterDialog(hdlg);
return TRUE;
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wparam, lparam))
{
case IDC_PERSPECT:
case IDC_PARALLEL:
par_flag = (wparam - IDC_PERSPECT != 0) ? TRUE :
FALSE;
CheckRadioButton(hdlg, IDC_PERSPECT, IDC_PARALLEL,
wparam);
break;
case IDC_HELP_SETCAMERA: // Display Help
WinHelp(hdlg, HelpFileName, HELP_CONTEXT,
(DWORD) HELP_SETCAMERA);
break;
case IDOK:
case IDC_UPDATE:
// Validate distances
vpd = GetDlgItemFloat(hdlg, IDC_VDIST);
fpd = GetDlgItemFloat(hdlg, IDC_FDIST);
bpd = GetDlgItemFloat(hdlg, IDC_BDIST);
if (vpd <= 0.0)
{
MessageBox(hdlg, ViewDistError, AppName,
MB_ICONEXCLAMATION | MB_OK);
return FALSE;
}
if (fpd >= bpd)
{
MessageBox(hdlg, FrontDistError, AppName,
MB_ICONEXCLAMATION | MB_OK);
return FALSE;
}
if (fpd < -(vpd - MIN_VALUE))
{
MessageBox(hdlg, EyeDistError, AppName,
MB_ICONEXCLAMATION | MB_OK);
return FALSE;
}
// Validate window scaling factor
scale = GetDlgItemFloat(hdlg, IDC_SCALE);
if (scale <= 0.0)
{
MessageBox(hdlg, WindowScaleError, AppName,
MB_ICONEXCLAMATION | MB_OK);
return FALSE;
}
// Validate bitmap window dimensions
w = (int) GetDlgItemInt(hdlg, IDC_HPIXSZ, &dummy,
FALSE);
h = (int) GetDlgItemInt(hdlg, IDC_VPIXSZ, &dummy,
FALSE);
if (w < MinPixel || w > MaxPixel || h < MinPixel
|| h > MaxPixel)
{
MessageBox(hdlg, PixelError, AppName,
MB_ICONEXCLAMATION | MB_OK);
return FALSE;
}
// Validate tilt angle
tilt = GetDlgItemFloat(hdlg, IDC_CAMTILT);
if (tilt < 0.0 || tilt > 360.0)
{
MessageBox(hdlg, TiltError, AppName,
MB_ICONEXCLAMATION | MB_OK);
return FALSE;
}
// Set distances
Camera.SetViewDist(vpd);
Camera.SetFrontDist(fpd);
Camera.SetBackDist(bpd);
// Set window scaling factor
Camera.SetWindowScale(scale);
// Set bitmap window dimensions
Camera.SetWidth(w);
Camera.SetHeight(h);
// Set camera tilt angle
Camera.SetTiltAngle(DegToRad(tilt));
// Set projection type
Camera.SetParProjFlag(par_flag);
// Update view system parameters
Camera.UpdateViewSystem();
// Instruct parent window to update client area
SendMessage(GetParent(hdlg), WM_COMMAND,
IDD_UPD_DISPLAY, 0L);
if (GET_WM_COMMAND_ID(wparam, lparam) == IDOK)
{
DestroyWindow(hdlg); // Close dialog box
hSetCameraDlg = NULL;
}
return TRUE;
case IDCANCEL:
DestroyWindow(hdlg); // Close dialog box
hSetCameraDlg = NULL;
return TRUE;
default:
break;
}
break;
case WM_CLOSE:
DestroyWindow(hdlg); // Close dialog box
hSetCameraDlg = NULL;
return TRUE;
default:
break;
}
return FALSE;
}
// Set camera view parameters
BOOL CALLBACK SetView( HWND hdlg, UINT msg, WPARAM
wparam, LPARAM lparam )
{
Point3 eye_posn; // Camera eye position
Point3 focus_posn; // Camera focus position
Vector3 temp; // Temporary vector
Vector3 view_dir; // View direction vector
Vector3 view_up; // View-up vector
switch (msg)
{
case WM_INITDIALOG:
// Get camera eye position
eye_posn = Camera.GetEyePosn();
SetDlgItemFloat(hdlg, IDC_EYE_X, eye_posn.GetX());
SetDlgItemFloat(hdlg, IDC_EYE_Y, eye_posn.GetY());
SetDlgItemFloat(hdlg, IDC_EYE_Z, eye_posn.GetZ());
// Get camera focus position
focus_posn = Camera.GetFocusPosn();
SetDlgItemFloat(hdlg, IDC_FOCUS_X, focus_posn.GetX());
SetDlgItemFloat(hdlg, IDC_FOCUS_Y, focus_posn.GetY());
SetDlgItemFloat(hdlg, IDC_FOCUS_Z, focus_posn.GetZ());
CenterDialog(hdlg);
return TRUE;
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wparam, lparam))
{
case IDC_HELP_SETVIEW: // Display Help
WinHelp(hdlg, HelpFileName, HELP_CONTEXT,
(DWORD) HELP_SETVIEW);
break;
case IDOK:
case IDC_UPDATE:
// Get eye position
eye_posn.SetX(GetDlgItemFloat(hdlg, IDC_EYE_X));
eye_posn.SetY(GetDlgItemFloat(hdlg, IDC_EYE_Y));
eye_posn.SetZ(GetDlgItemFloat(hdlg, IDC_EYE_Z));
// Get focus position
focus_posn.SetX(GetDlgItemFloat(hdlg,
IDC_FOCUS_X));
focus_posn.SetY(GetDlgItemFloat(hdlg,
IDC_FOCUS_Y));
focus_posn.SetZ(GetDlgItemFloat(hdlg,
IDC_FOCUS_Z));
// Validate eye and focus positions
temp = Vector3(eye_posn, focus_posn);
if (fabs(temp.Length()) < MIN_VALUE)
{
MessageBox(hdlg, FocusError, AppName,
MB_ICONEXCLAMATION | MB_OK);
return FALSE;
}
// Set camera view parameters
Camera.SetEyeFocusPosn(eye_posn, focus_posn);
// Update view system parameters
Camera.UpdateViewSystem();
// Instruct parent window to update client area
SendMessage(GetParent(hdlg), WM_COMMAND,
IDD_UPD_DISPLAY, 0L);
if (GET_WM_COMMAND_ID(wparam, lparam) == IDOK)
{
DestroyWindow(hdlg); // Close dialog box
hSetViewDlg = NULL;
}
return TRUE;
case IDCANCEL:
DestroyWindow(hdlg); // Close dialog box
hSetViewDlg = NULL;
return TRUE;
default:
break;
}
break;
case WM_CLOSE:
DestroyWindow(hdlg); // Close dialog box
hSetViewDlg = NULL;
return TRUE;
default:
break;
}
return FALSE;
}
// Set radiosity rendering convergence parameters
BOOL CALLBACK SetConverge( HWND hdlg, UINT msg, WPARAM
wparam, LPARAM lparam )
{
int mp; // Maximum number of steps
double sc; // Stopping criterion
BOOL dummy; // Dummy parameter
switch (msg)
{
case WM_INITDIALOG:
SetDlgItemInt(hdlg, IDC_MSTEP, Radiosity.GetMaxStep(),
FALSE);
SetDlgItemFloat(hdlg, IDC_STOPC,
Radiosity.GetStopCriterion());
CheckDlgButton(hdlg, IDC_AMBIENT_EN,
Radiosity.AmbientFlag());
if (Radiosity.OverShootFlag() == TRUE)
CheckDlgButton(hdlg, IDC_OVER_EN, TRUE);
CenterDialog(hdlg);
return TRUE;
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wparam, lparam))
{
case IDC_HELP_SETCONVERGE: // Display Help
WinHelp(hdlg, HelpFileName, HELP_CONTEXT,
(DWORD) HELP_SETCONVERGE);
break;
case IDOK:
// Validate parameters
mp = GetDlgItemInt(hdlg, IDC_MSTEP, &dummy, TRUE);
sc = GetDlgItemFloat(hdlg, IDC_STOPC);
if (mp < 1 || mp > MaxStep)
{
MessageBox(hdlg, MaxStepError, AppName,
MB_ICONEXCLAMATION | MB_OK);
return FALSE;
}
if (sc <= 0.0 || sc > 1.0)
{
MessageBox(hdlg, StopError, AppName,
MB_ICONEXCLAMATION | MB_OK);
return FALSE;
}
// Set convergence parameters
Radiosity.SetMaxStep(mp);
Radiosity.SetStopCriterion(sc);
if (IsDlgButtonChecked(hdlg, IDC_AMBIENT_EN) != 0)
Radiosity.EnableAmbient();
else
Radiosity.DisableAmbient();
if (IsDlgButtonChecked(hdlg, IDC_OVER_EN) != 0)
Radiosity.EnableOverShoot();
else
Radiosity.DisableOverShoot();
EndDialog(hdlg, TRUE);
return TRUE;
case IDCANCEL:
EndDialog(hdlg, FALSE);
return TRUE;
default:
break;
}
break;
default:
break;
}
return FALSE;
}
// Set display parameters
BOOL CALLBACK SetDisplay( HWND hdlg, UINT msg, WPARAM
wparam, LPARAM lparam )
{
int i; // Loop index
int noise; // Noise parameter
double contrast; // Contrast value
double gamma; // Gamma parameter
double intensity; // Intensity value
BOOL dummy; // Dummy parameter
switch (msg)
{
case WM_INITDIALOG:
SetDlgItemFloat(hdlg, IDC_INTENS,
Camera.GetIntensity());
SetDlgItemFloat(hdlg, IDC_CONTRAST,
Camera.GetContrast());
SetDlgItemFloat(hdlg, IDC_GAMMA, Camera.GetGamma());
SetDlgItemInt(hdlg, IDC_JITTER,
Camera.GetNoiseLevel(), FALSE);
CheckDlgButton(hdlg, IDC_INTENS_EN,
Camera.IntensityFlag());
CheckDlgButton(hdlg, IDC_CONTRAST_EN,
Camera.ContrastFlag());
CheckDlgButton(hdlg, IDC_GAMMA_EN,
Camera.GammaFlag());
CheckDlgButton(hdlg, IDC_JITTER_EN,
Camera.JitterFlag());
// Initialize filter selection combo box
for (i = 0; i < Camera.GetNumFilters(); i++)
SendDlgItemMessage(hdlg, IDC_FILTERSEL,
CB_INSERTSTRING, i, (LPARAM)
Camera.GetFilterSize(i));
// Select current antialiasing filter
(void) SendDlgItemMessage(hdlg, IDC_FILTERSEL,
CB_SELECTSTRING, -1, (LONG)
Camera.GetCurrFilterSize());
CenterDialog(hdlg);
return TRUE;
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wparam, lparam))
{
case IDC_HELP_SETDISPLAY: // Display Help
WinHelp(hdlg, HelpFileName, HELP_CONTEXT,
(DWORD) HELP_SETDISPLAY);
break;
case IDOK:
case IDC_UPDATE:
intensity = GetDlgItemFloat(hdlg, IDC_INTENS);
// Set intensity parameter
Camera.SetIntensity(intensity);
contrast = GetDlgItemFloat(hdlg, IDC_CONTRAST);
if (contrast <= 0.0)
{
MessageBox(hdlg, ContrastError, AppName,
MB_ICONEXCLAMATION | MB_OK);
return FALSE;
}
// Set contrast parameter
Camera.SetContrast(contrast);
gamma = GetDlgItemFloat(hdlg, IDC_GAMMA);
if (gamma <= 0.0)
{
MessageBox(hdlg, GammaError, AppName,
MB_ICONEXCLAMATION | MB_OK);
return FALSE;
}
// Set gamma correction parameter
Camera.SetGamma(gamma);
noise = GetDlgItemInt(hdlg, IDC_JITTER, &dummy,
TRUE);
if (noise < 0 || noise > 8)
{
MessageBox(hdlg, NoiseError, AppName,
MB_ICONEXCLAMATION | MB_OK);
return FALSE;
}
// Set noise level parameter
Camera.SetNoiseLevel(noise);
// Set antialiasing filter type
Camera.SetFilterType((int)
SendDlgItemMessage(hdlg, IDC_FILTERSEL,
CB_GETCURSEL, 0, 0L));
if (IsDlgButtonChecked(hdlg, IDC_INTENS_EN) != 0)
Camera.EnableIntensity();
else
Camera.DisableIntensity();
if (IsDlgButtonChecked(hdlg, IDC_CONTRAST_EN) != 0)
Camera.EnableContrast();
else
Camera.DisableContrast();
if (IsDlgButtonChecked(hdlg, IDC_GAMMA_EN) != 0)
Camera.EnableGamma();
else
Camera.DisableGamma();
if (IsDlgButtonChecked(hdlg, IDC_JITTER_EN) != 0)
Camera.EnableJitter();
else
Camera.DisableJitter();
if (DispType == H_BMAP)
{
// Instruct parent window to update client area
SendMessage(GetParent(hdlg), WM_COMMAND,
IDD_UPD_DISPLAY, 0L);
}
if (GET_WM_COMMAND_ID(wparam, lparam) == IDOK)
{
DestroyWindow(hdlg); // Close dialog box
hSetDisplayDlg = NULL;
}
return TRUE;
case IDCANCEL:
DestroyWindow(hdlg); // Close dialog box
hSetDisplayDlg = NULL;
return TRUE;
default:
break;
}
break;
case WM_CLOSE:
DestroyWindow(hdlg); // Close dialog box
hSetDisplayDlg = NULL;
return TRUE;
default:
break;
}
return FALSE;
}
// Set color parameters
BOOL CALLBACK SetColor( HWND hdlg, UINT msg, WPARAM
wparam, LPARAM lparam )
{
static int c_type; // Color type
static BOOL r_flag; // Color resolution flag
switch (msg)
{
case WM_INITDIALOG:
c_type = Camera.GetColorType();
r_flag = Bitmap.GetRGBFlag();
CheckRadioButton(hdlg, IDC_RGB, IDC_PSEUDO, c_type +
IDC_RGB);
if (Bitmap.GetPaletteFlag() == FALSE)
{
if (r_flag == TRUE)
CheckRadioButton(hdlg, IDC_COLRES_24, IDC_COLRES_8,
IDC_COLRES_24);
else
CheckRadioButton(hdlg, IDC_COLRES_24, IDC_COLRES_8,
IDC_COLRES_8);
}
else
{
// Disable 24-bit color resolution button
EnableWindow(GetDlgItem(hdlg, IDC_COLRES_24),
FALSE);
CheckRadioButton(hdlg, IDC_COLRES_24, IDC_COLRES_8,
IDC_COLRES_8);
}
CenterDialog(hdlg);
return TRUE;
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wparam, lparam))
{
case IDC_RGB:
case IDC_MONO:
case IDC_PSEUDO:
switch (wparam - IDC_RGB)
{
case 0:
c_type = SC_RGB;
break;
case 1:
c_type = SC_MONO;
break;
case 2:
c_type = SC_PSEUDO;
break;
default:
break;
}
CheckRadioButton(hdlg, IDC_RGB, IDC_PSEUDO,
wparam);
break;
case IDC_COLRES_8:
case IDC_COLRES_24:
r_flag = (wparam - IDC_COLRES_24 == 0) ? TRUE :
FALSE;
CheckRadioButton(hdlg, IDC_COLRES_24,
IDC_COLRES_8, wparam);
break;
case IDC_HELP_SETDISPLAY: // Display Help
WinHelp(hdlg, HelpFileName, HELP_CONTEXT,
(DWORD) HELP_SETCOLOR);
break;
case IDOK:
case IDC_UPDATE:
// Set display color type
Camera.SetColorType(c_type);
// Set display color resolution
Bitmap.SetRGBFlag(r_flag);
if (DispType == H_BMAP)
{
// Instruct parent window to update client area
SendMessage(GetParent(hdlg), WM_COMMAND,
IDD_UPD_DISPLAY, 0L);
}
if (GET_WM_COMMAND_ID(wparam, lparam) == IDOK)
{
DestroyWindow(hdlg); // Close dialog box
hSetColorDlg = NULL;
}
return TRUE;
case IDCANCEL:
DestroyWindow(hdlg); // Close dialog box
hSetColorDlg = NULL;
return TRUE;
default:
break;
}
break;
case WM_CLOSE:
DestroyWindow(hdlg); // Close dialog box
hSetColorDlg = NULL;
return TRUE;
default:
break;
}
return FALSE;
}
// Abort calculations dialog box
BOOL CALLBACK AbortCalc( HWND hdlg, UINT msg, WPARAM
wparam, LPARAM lparam )
{
switch (msg)
{
case WM_INITDIALOG:
SetFocus(GetDlgItem(hdlg, IDCANCEL));
CenterDialog(hdlg);
return TRUE;
case WM_COMMAND:
AbortFlag = TRUE;
return TRUE;
default:
break;
}
return FALSE;
}
// Rendering calculations dialog box
BOOL CALLBACK RenderMsg( HWND hdlg, UINT msg, WPARAM
wparam, LPARAM lparam )
{
switch (msg)
{
case WM_INITDIALOG:
CenterDialog(hdlg);
return TRUE;
default:
break;
}
return FALSE;
}
// Display About dialog box
BOOL CALLBACK About( HWND hdlg, UINT msg, WPARAM wparam,
LPARAM lparam )
{
switch (msg)
{
case WM_INITDIALOG:
CenterDialog(hdlg);
return TRUE;
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wparam, lparam))
{
case IDOK:
case IDCANCEL:
EndDialog(hdlg, TRUE);
return TRUE;
default:
break;
}
break;
default:
break;
}
return FALSE;
}
// Set camera movement type
static void SetMovementType( HMENU hmenu, UINT menu_id )
{
HMENU hintm; // Interactive menu handle
BOOL check; // Check mark status
// Get interactive menu handle
hintm = GetSubMenu(GetSubMenu(hmenu, MENU_CAMERA_POS),
MENU_INTERACTIVE_POS);
// Save current menu item state
check = GetMenuState(hintm, menu_id, MF_BYCOMMAND) &
MF_CHECKED;
// Clear menu item check marks
CheckMenuItem(hintm, IDM_SETDOLLY, MF_UNCHECKED);
CheckMenuItem(hintm, IDM_SETORBIT, MF_UNCHECKED);
CheckMenuItem(hintm, IDM_SETPAN, MF_UNCHECKED);
CheckMenuItem(hintm, IDM_SETROTATE, MF_UNCHECKED);
CheckMenuItem(hintm, IDM_SETTILT, MF_UNCHECKED);
CheckMenuItem(hintm, IDM_SETZOOM, MF_UNCHECKED);
if (check == FALSE)
{
// Check current menu item
CheckMenuItem(hintm, menu_id, MF_CHECKED);
// Update camera movement type
switch (menu_id)
{
case IDM_SETDOLLY:
MoveType = H_DOLLY;
break;
case IDM_SETORBIT:
MoveType = H_ORBIT;
break;
case IDM_SETPAN:
MoveType = H_PAN;
break;
case IDM_SETROTATE:
MoveType = H_ROTATE;
break;
case IDM_SETTILT:
MoveType = H_TILT;
break;
case IDM_SETZOOM:
MoveType = H_ZOOM;
break;
default:
break;
}
}
else
MoveType = H_LOCK; // Disable camera movement
}
// Disable all menu items
static void DisableMenu( HMENU hmenu )
{
EnableMenuItem(hmenu, IDM_FILEOPEN, MF_GRAYED);
EnableMenuItem(hmenu, IDM_SAVEAS, MF_GRAYED);
EnableMenuItem(hmenu, IDM_DIRECTORY, MF_GRAYED);
EnableMenuItem(hmenu, IDM_STATISTICS, MF_GRAYED);
EnableMenuItem(hmenu, IDM_EXIT, MF_GRAYED);
EnableMenuItem(hmenu, IDM_SETCAMERA, MF_GRAYED);
EnableMenuItem(hmenu, IDM_SETVIEW, MF_GRAYED);
EnableMenuItem(hmenu, IDM_DEFVIEW, MF_GRAYED);
EnableMenuItem(GetSubMenu(hmenu, MENU_CAMERA_POS),
MENU_INTERACTIVE_POS, MF_GRAYED | MF_BYPOSITION);
EnableMenuItem(hmenu, IDM_WIREFRAME, MF_GRAYED);
EnableMenuItem(hmenu, IDM_SHADED, MF_GRAYED);
EnableMenuItem(hmenu, IDM_RENDER, MF_GRAYED);
EnableMenuItem(hmenu, IDM_REDISPLAY, MF_GRAYED);
EnableMenuItem(hmenu, IDM_SETDISPLAY, MF_GRAYED);
EnableMenuItem(hmenu, IDM_SETCOLOR, MF_GRAYED);
EnableMenuItem(hmenu, IDM_SETCONVERGE, MF_GRAYED);
EnableMenuItem(hmenu, IDM_HELP_CONTENTS, MF_GRAYED);
EnableMenuItem(hmenu, IDM_HELP_HELP, MF_GRAYED);
EnableMenuItem(hmenu, IDM_HELP_BOOK, MF_GRAYED);
EnableMenuItem(hmenu, IDM_ABOUT, MF_GRAYED);
}
// Enable menu items
static void EnableMenu( HMENU hmenu )
{
EnableMenuItem(hmenu, IDM_FILEOPEN, MF_ENABLED);
EnableMenuItem(hmenu, IDM_DIRECTORY, MF_ENABLED);
EnableMenuItem(hmenu, IDM_STATISTICS, MF_ENABLED);
EnableMenuItem(hmenu, IDM_EXIT, MF_ENABLED);
EnableMenuItem(hmenu, IDM_SETCAMERA, MF_ENABLED);
EnableMenuItem(hmenu, IDM_SETVIEW, MF_ENABLED);
EnableMenuItem(hmenu, IDM_DEFVIEW, MF_ENABLED);
EnableMenuItem(GetSubMenu(hmenu, MENU_CAMERA_POS),
MENU_INTERACTIVE_POS, MF_ENABLED | MF_BYPOSITION);
EnableMenuItem(hmenu, IDM_WIREFRAME, MF_ENABLED);
EnableMenuItem(hmenu, IDM_SHADED, MF_ENABLED);
EnableMenuItem(hmenu, IDM_REDISPLAY, MF_ENABLED);
EnableMenuItem(hmenu, IDM_SETDISPLAY, MF_ENABLED);
EnableMenuItem(hmenu, IDM_SETCOLOR, MF_ENABLED);
EnableMenuItem(hmenu, IDM_SETCONVERGE, MF_ENABLED);
EnableMenuItem(hmenu, IDM_HELP_CONTENTS, MF_ENABLED);
EnableMenuItem(hmenu, IDM_HELP_HELP, MF_ENABLED);
EnableMenuItem(hmenu, IDM_HELP_BOOK, MF_ENABLED);
EnableMenuItem(hmenu, IDM_ABOUT, MF_ENABLED);
if (RadCalcDone == FALSE)
EnableMenuItem(hmenu, IDM_RENDER, MF_ENABLED);
if (DispType == H_BMAP)
EnableMenuItem(hmenu, IDM_SAVEAS, MF_ENABLED);
}
// Display bitmap
static BOOL DisplayBitmap( HWND hwnd, HWND hwnd_wire, HMENU
hmenu )
{
BOOL r_abort; // Rendering abort flag
BOOL repeat; // Repeat flag
BOOL status; // Status flag
DLGPROC pfunc; // Exported fcn prolog ptr
DisableMenu(hmenu); // Disable menu items
// Create modeless rendering calculations dialog box
if (Camera.AntiAliasFlag() == TRUE)
{
InCalc = TRUE;
pfunc = (DLGPROC) MakeProcInstance((FARPROC) AbortCalc,
hInst);
hAbortDlg = CreateDialog(hInst, "AbortRender", hwnd,
(DLGPROC) pfunc);
SetDlgItemInt(hAbortDlg, IDC_MAXPASS,
Camera.GetMaxPass(), FALSE);
SetDlgItemInt(hAbortDlg, IDC_NUMPASS,
Camera.GetNumPass(), FALSE);
SetDlgItemText(hAbortDlg, IDC_FILTERTYPE,
Camera.GetCurrFilterName());
}
else
{
pfunc = (DLGPROC) MakeProcInstance((FARPROC) RenderMsg,
hInst);
hRenderDlg = CreateDialog(hInst, "RenderMsg", hwnd,
(DLGPROC) pfunc);
}
// Record shaded display
r_abort = FALSE;
do
{
if ((status = Camera.Shoot(&Environment, &Bitmap,
&repeat)) == FALSE)
break;
if (Camera.AntiAliasFlag() == TRUE)
{
// Update dialog box
SetDlgItemInt(hAbortDlg, IDC_NUMPASS,
Camera.GetNumPass(), FALSE);
// Check for user-requested abort
if (CheckAbort() == TRUE)
{
r_abort = TRUE;
AbortFlag = FALSE;
Camera.Abort();
break;
}
}
}
while (repeat == TRUE);
// Close rendering calculations dialog box
if (Camera.AntiAliasFlag() == TRUE)
{
InCalc = FALSE;
DestroyWindow(hAbortDlg);
}
else
DestroyWindow(hRenderDlg);
FreeProcInstance((FARPROC) pfunc);
UpdateWindow(hwnd);
if (status == TRUE && r_abort == FALSE)
{
// 256-color display required ?
if (Bitmap.GetRGBFlag() == FALSE)
{
// Create modeless color quantization dialog box
pfunc = (DLGPROC) MakeProcInstance((FARPROC)
RenderMsg, hInst);
hRenderDlg = CreateDialog(hInst, "QuantizeMsg", hwnd,
(DLGPROC) pfunc);
// Perform color quantization
status = Bitmap.QuantizeColors();
// Close color quantization dialog box
DestroyWindow(hRenderDlg);
FreeProcInstance((FARPROC) pfunc);
UpdateWindow(hwnd);
}
}
if (status == TRUE) // Check for error
{
if (DispType == H_WIRE)
{
// Erase wireframe metafile
Wire.Erase();
// Destroy wireframe window
DestroyWindow(hwnd_wire);
}
if (r_abort == FALSE)
{
DispType = H_BMAP;
// Initialize scroll bar manager
pScroll->Init(Camera.GetWidth(), Camera.GetHeight());
// Enable Save As menu item
EnableMenuItem(hmenu, IDM_SAVEAS, MF_ENABLED);
}
else
{
DispType = H_NONE;
pScroll->Hide(); // Hide scroll bars
}
}
else
OutOfMemory(); // Report error
// Redraw display (via WM_PAINT)
InvalidateRect(hwnd, NULL, TRUE);
EnableMenu(hmenu); // Enable menu items
if (status == TRUE && r_abort == FALSE)
return TRUE;
else
return FALSE;
}
// Update camera dolly
static void UpdateDolly( int mdy )
{
double dist_mult; // Dolly distance multiplier
// Calculate dolly distance (range -1.0 to 1.0)
dist_mult = (double) mdy / (double)
GetSystemMetrics(SM_CYSCREEN);
Camera.Dolly(dist_mult); // Dolly camera
// Update modeless View Parameters dialog box
UpdateViewDialog();
}
// Update camera orbit
static void UpdateOrbit( int mdx, int mdy )
{
double h_rotate; // Horizontal rotation angle
double v_rotate; // Vertical rotation angle
// Calculate horizontal rotation angle (range:
// -aspect_ratio to aspect_ratio)
h_rotate = PI * (double) mdx / (4.0 * (double)
GetSystemMetrics(SM_CYSCREEN));
// Calculate vertical rotation angle (range: -1 to 1)
v_rotate = PI * (double) mdy / (4.0 * (double)
GetSystemMetrics(SM_CYSCREEN));
// Orbit camera
Camera.Orbit(h_rotate, v_rotate);
// Update modeless View Parameters dialog box
UpdateViewDialog();
}
// Update camera pan
static void UpdatePan( int mdx, int mdy )
{
double horz_mult; // Horizontal pan multiplier
double vert_mult; // Vertical pan multiplier
// Calculate horizontal pan multiplier (range -1.0 *
// aspect_ratio to 1.0 * aspect_ratio)
horz_mult = (double) mdx / (double)
GetSystemMetrics(SM_CYSCREEN);
// Calculate vertical pan multiplier (range -1.0 to
// 1.0)
vert_mult = (double) mdy / (double)
GetSystemMetrics(SM_CYSCREEN);
Camera.Pan(horz_mult, vert_mult); // Pan camera
// Update modeless View Parameters dialog box
UpdateViewDialog();
}
// Update camera rotate
static void UpdateRotate( int mdx, int mdy )
{
double h_rotate; // Horizontal rotation angle
double v_rotate; // Vertical rotation angle
// Calculate horizontal rotation angle (range:
// -aspect_ratio to aspect_ratio)
h_rotate = PI * (double) mdx / (4.0 * (double)
GetSystemMetrics(SM_CYSCREEN));
// Calculate vertical rotation angle (range: -1 to 1)
v_rotate = PI * (double) mdy / (4.0 * (double)
GetSystemMetrics(SM_CYSCREEN));
// Rotate camera
Camera.Rotate(h_rotate, v_rotate);
// Update modeless View Parameters dialog box
UpdateViewDialog();
}
// Update camera tilt
static void UpdateTilt( int mdx )
{
double tilt_angle; // Tilt angle
// Calculate rotation angle (range: -1 to 1)
tilt_angle = PI * (double) mdx / (4.0 * (double)
GetSystemMetrics(SM_CXSCREEN));
// Tilt camera
Camera.Tilt(tilt_angle);
// Update modeless Camera Parameters dialog box
UpdateCameraDialog();
}
// Update camera zoom
static void UpdateZoom( int mdy )
{
double vd_mult; // View distance multiplier
// Calculate view distance multiplier (range 0.25 to 4.0)
vd_mult = pow(2.0, (2.0 + (double) (2 * mdy) / (double)
GetSystemMetrics(SM_CYSCREEN))) / 4.0;
Camera.Zoom(vd_mult); // Zoom camera
// Update modeless Camera Parameters dialog box
UpdateCameraDialog();
}
// Update modeless Camera Parameters dialog box
static void UpdateCameraDialog()
{
if (hSetCameraDlg != NULL)
{
// Update view distance edit control
SetDlgItemFloat(hSetCameraDlg, IDC_VDIST,
Camera.GetViewDist());
// Update front distance edit control
SetDlgItemFloat(hSetCameraDlg, IDC_FDIST,
Camera.GetFrontDist());
// Update back distance edit control
SetDlgItemFloat(hSetCameraDlg, IDC_BDIST,
Camera.GetBackDist());
// Update camera tilt angle
SetDlgItemFloat(hSetCameraDlg, IDC_CAMTILT,
RadToDeg(Camera.GetTiltAngle()));
}
}
// Update modeless View Parameters dialog box
static void UpdateViewDialog()
{
if (hSetViewDlg != NULL)
{
// Update eye position edit controls
SetDlgItemFloat(hSetViewDlg, IDC_EYE_X,
Camera.GetEyePosn().GetX());
SetDlgItemFloat(hSetViewDlg, IDC_EYE_Y,
Camera.GetEyePosn().GetY());
SetDlgItemFloat(hSetViewDlg, IDC_EYE_Z,
Camera.GetEyePosn().GetZ());
// Update focus position edit controls
SetDlgItemFloat(hSetViewDlg, IDC_FOCUS_X,
Camera.GetFocusPosn().GetX());
SetDlgItemFloat(hSetViewDlg, IDC_FOCUS_Y,
Camera.GetFocusPosn().GetY());
SetDlgItemFloat(hSetViewDlg, IDC_FOCUS_Z,
Camera.GetFocusPosn().GetZ());
}
}
// Display Interactive popup menu
static void DispInteractMenu( HWND hwnd, HMENU hmenu, POINT
point )
{
ClientToScreen(hwnd, (LPPOINT) &point);
TrackPopupMenu(hmenu, 0, point.x, point.y, 0, hwnd, NULL);
}
// Get floating point dialog item
static double GetDlgItemFloat( HWND hdlg, int id )
{
(void) GetDlgItemText(hdlg, id, StrBuffer,
sizeof(StrBuffer));
return atof(StrBuffer);
}
// Set floating point dialog item
static void SetDlgItemFloat( HWND hdlg, int id, double num )
{
sprintf(StrBuffer, "%6.5f", num);
SetDlgItemText(hdlg, id, StrBuffer);
}
// Calculate wireframe window dimensions
static void CalcWireDim( short client_x, short client_y,
short *pxchild, short *pychild )
{
double client_aspect;
double child_aspect;
if (client_y > 0)
{
client_aspect = (double) client_x / (double) client_y;
child_aspect = (double) Camera.GetWidth() / (double)
Camera.GetHeight();
if (client_aspect >= child_aspect)
{
*pychild = (short) max(client_y - Offset * 2, Offset);
*pxchild = (short) ((double) *pychild * child_aspect);
}
else
{
*pxchild = (short) max(client_x - Offset * 2, Offset);
*pychild = (short) ((double) *pxchild / child_aspect);
}
}
else
*pxchild = *pychild = Offset;
}
// Process WM_KEYDOWN message
static void DoKeyDown( HWND hwnd, WPARAM wparam )
{
switch (GET_WM_COMMAND_ID(wparam, lparam))
{
case VK_HOME:
SendMessage(hwnd, WM_VSCROLL, SB_TOP, 0L);
break;
case VK_END:
SendMessage(hwnd, WM_VSCROLL, SB_BOTTOM, 0L);
break;
case VK_PRIOR:
SendMessage(hwnd, WM_VSCROLL, SB_PAGEUP, 0L);
break;
case VK_NEXT:
SendMessage(hwnd, WM_VSCROLL, SB_PAGEDOWN, 0L);
break;
case VK_UP:
SendMessage(hwnd, WM_VSCROLL, SB_LINEUP, 0L);
break;
case VK_DOWN:
SendMessage(hwnd, WM_VSCROLL, SB_LINEDOWN, 0L);
break;
case VK_LEFT:
SendMessage(hwnd, WM_HSCROLL, SB_PAGEUP, 0L);
break;
case VK_RIGHT:
SendMessage(hwnd, WM_HSCROLL, SB_PAGEDOWN, 0L);
break;
}
}
// Check for user-requested abort
static BOOL CheckAbort()
{
MSG msg; // Window message
// Process application message queue
while ((AbortFlag == FALSE) && (PeekMessage(&msg, NULL,
0, 0, PM_REMOVE)))
{
if (IsDialogMessage(hAbortDlg, &msg) == FALSE)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return AbortFlag;
}
// Center dialog box
static void CenterDialog( HWND hdlg )
{
int height; // Dialog box height
int width; // Dialog box width
RECT drc; // Dialog box coordinates
RECT wrc; // Parent window coordinates
// Get dialog box coordinates
GetWindowRect(hdlg, &drc);
height = drc.bottom - drc.top;
width = drc.right - drc.left;
// Get parent window coordinates
GetWindowRect(GetWindow(hdlg, GW_OWNER), &wrc);
// Center dialog box in parent window
MoveWindow(hdlg, max(0, (wrc.left + wrc.right - width) /
2), max(0, (wrc.top + wrc.bottom - height) / 2),
width, height, FALSE);
}